/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package chatsystem;

import java.net.InetAddress;
import java.util.ArrayList;
import javax.swing.AbstractListModel;
import javax.swing.event.ListDataListener;

/**
 *
 * @author Maël
 */
public class ListeUtilisateurs extends AbstractListModel {

    private ArrayList<Utilisateur> users;
    private ListDataListener listener;

    /**
     * Crée une nouvelle liste d'utilisateurs
     */
    public ListeUtilisateurs() {
        users = new ArrayList();
    }

    /**
     * Ajoute un nouvel utilisateur à la liste
     * @param name nom de l'utilisateur
     * @param address adresse IP de l'utilisateur
     */
    public void addUser(String name, InetAddress address) {
        this.users.add(new Utilisateur(name, address));
        if (listener != null) {
            //listener.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, 0, users.size()));
        }
        this.fireIntervalAdded(this, 0, users.size());
    }
    
    /**
     * Change le nom d'un utilisateur
     * @param name nouveau nom
     * @param addr adresse IP de l'utilisateur à modifier
     */
    void replaceUser(String name, InetAddress addr) {
        int i = 0;
        while (i < users.size() && !users.get(i).getAddress().equals(addr)) {
            i++;
        }
        if (i == users.size()) {
            System.out.println("Erreur : user not found in the list");
        } else {
            users.remove(i);
            users.add(new Utilisateur(name, addr));
            if (listener != null) {
                //listener.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, 0, users.size()));
            }
            this.fireContentsChanged(this, i, i);
        }
    }

    /**
     * Supprime l'utilisateur de nom name
     * @param name nom de l'utilisateur à supprimer
     */
    public void delUserByName(String name) {
        this.fireIntervalRemoved(this, getIndexFromName(name), getIndexFromName(name));
        this.users.remove(getIndexFromName(name));
        
    }
    
    /**
     * Méthode qui vide la liste des utilisateurs
     */
    public void flush() {
        //int taille= this.getSize();
        for (int i=0; i<this.getSize(); i++) {
            this.users.remove(0);
        }
        //this.fireIntervalRemoved(this, 0, taille);
    }
    
    /**
     * Supprime l'utilisateur d'adresse IP addr
     * @param addr adresse IP de l'utilisateur à supprimer
     */
    public void removeUserByAddr(InetAddress addr) {
        int i = 0;
        while (i < users.size() && !users.get(i).getAddress().equals(addr)) {
            i++;
        }
        if (i == users.size()) {
            System.out.println("Erreur : user not found in the list");
        } else {
            users.remove(i);
            if (listener != null) {
                //listener.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, 0, users.size()));
            }
            this.fireIntervalRemoved(this, 0, users.size());
        }
    }

    /**
     * Renvoie l'adresse IP de l'utilisateur de nom name
     * @param name nom de l'utilisateur dont on cherche l'adresse IP
     * @return l'adresse IP si l'utilisateur existe
     * @throws NoSuchFieldException 
     */
    public InetAddress getByName(String name) throws NoSuchFieldException {
        Utilisateur user = null;
        Boolean trouve = false;
        int cpt = 0;

        while (!trouve && cpt<users.size()) {
            if (users.get(cpt).getUserName().equals(name)) {
                user = users.get(cpt);
                trouve = true;
            }
            cpt++;
        }
        if (trouve)
            return user.getAddress();
        else
            throw new NoSuchFieldException("User not found");
    }

    /**
     * Renvoie l'utilisateur d'adresse IP addr
     * @param addr adresse IP de l'utilisateur que l'on cherche
     * @return l'utilisateur s'il existe, null sinon
     */
    public Utilisateur getUserByAddr(InetAddress addr) {
        int i = 0;
        while (i < users.size() && !users.get(i).getAddress().equals(addr)) {
            i++;
        }
        if (i == users.size()) {
            System.out.println("Erreur : user not found in the list");
            return null;
        } else {
            return users.get(i);
        }
    }

    /**
     * Renvoie l'index d'un utilisateur à partir de son nom
     * @param n nom de l'utilisateur que l'on cherche
     * @return l'index de l'utilisateur s'il existe, -1 sinon
     */
    public int getIndexFromName(String n) {
        int i=0;
        for (i=0; i<this.getSize(); i++) {
            if (this.users.get(i).getUserName().equals(n))
                    return i;
        }
        return -1;
    }
    

    @Override
    public int getSize() {
        return this.users.size();
    }

    @Override
    public Object getElementAt(int i) {
        return this.users.get(i);
    }

    /**
     * Affiche la liste des utilisateurs dans la console
     */
    public void displaytoString() {
        System.out.println("<ListeUser>");
        int cpt=0;
        while (cpt<this.users.size()) {
            System.out.println(this.users.get(cpt).toString());
            cpt++;
        }
        System.out.println("</ListeUser>\n");
    }

    /**
     * Cette méthode renvoie l'utilisateur correspondant au nom donné
     * @param name nom de l'utilisateur qu'on cherche
     * @return l'utilisateur s'il est dans la liste, null sinon
     */
    public Utilisateur getFromName(String name) {
        for (int i=0; i<this.getSize(); i++) {
            if (this.users.get(i).getUserName().equals(name))
                    return this.users.get(i);
        }
        
        return null;
    }
    
    /**
     * Dit si la liste d'utilisateur contient ou non name
     * @param name nom de l'utilisateur dont l'on teste l'appartenance à la liste
     * @return true si name fait partie de la liste, false sinon
     */
    public boolean contains (String name) {
        boolean result = false;
        if (this.getFromName(name)!=null) {
            result = true;
        }
        return result;
    }
    
}
